package com.yc.testThread;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class TestThreadPool {

    public static void main(String[] args) {
        TestThreadPool t = new TestThreadPool();
//        t.m1();
//        t.m2();
//        t.m4();
//        t.m5();
//        t.m6();
        t.m7();
//        t.m8();
//        t.m9();
//        t.m10();
//        t.m11();
    }

    /**
     * pool-1-thread-1----------start----
     * pool-1-thread-3----------start----
     * pool-1-thread-2----------start----
     * -----over
     * pool-1-thread-1----------end----
     * pool-1-thread-2----------end----
     * pool-1-thread-3----------end----
     */
    public void m1() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executorService.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "----------start----");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + "----------end----");
            });
        }

        executorService.shutdown();//创建完就关闭？
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("-----over");

    }

    /**
     * newFixedThreadPool
     */
    public void m2() {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
//        ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(3);
//        executorService.allowCoreThreadTimeOut(true);
        for (int i = 0; i < 3; i++) {
            executorService.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "----------start----");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + "----------end----");
            });
        }

        executorService.shutdown();//创建完就关闭？
        try {
            Thread.sleep(50000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("-----over");

    }

    /**
     * 自定义线程池
     */
//    public void m3() {
//        ExecutorService executorService = new ThreadPoolExecutor(int corePoolSize,
//        int maximumPoolSize,
//        long keepAliveTime,
//        TimeUnit unit,
//        BlockingQueue<Runnable> workQueue,
//        ThreadFactory threadFactory,
//        RejectedExecutionHandler handler);
//    }

    /**
     * submit有返回值
     */
    public void m4() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(() -> {
            System.out.println("----------start----");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("----------end----");
            return "ok";
        });

        System.out.println("------------------");
        try {
            System.out.println(future.get());//在这里阻塞，等待着线程池返回结果
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } finally {
            executorService.shutdown();
        }

        System.out.println("-----over");
    }

    /**
     * 对submit接收任务，然后捕获异常
     */
    public void m5() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(() -> {
            System.out.println("----------start----");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            int a = 1/0;
            System.out.println("----------end----");
            return "ok";
        });

        System.out.println("------------------");
        try {
            System.out.println(future.get());//在这里阻塞，等待着线程池返回结果
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } finally {
            executorService.shutdown();
        }

        System.out.println("-----over");
    }

    /**
     * 多线程运行，shutdown
     *  其他正在运行的线程会执行完，但不再接收新的任务（报错）
     */
    public void m6() {
        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                String threadName = Thread.currentThread().getName();
                System.out.println(threadName + ": ok");
            });
        }

        System.out.println("------------------");
        executorService.shutdown();

        //再次尝试添加任务
        executorService.execute(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + ": ok");
        });

        System.out.println("-----over");
    }

    /**
     * 多线程运行，shutdownNow()
     *  正在运行的线程都会停止
     */
    public void m7() {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": ok");
            });
        }

        List<Runnable> res = executorService.shutdownNow();
        System.out.println("-----over: " + res.size());
    }

    /**
     * 测试shutdownNow起效时间
     */
    public void m8() {
        ExecutorService service = Executors.newFixedThreadPool(2);
        for (int i = 1; i <= 5; i++) {
            String str = i + "";
            service.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(str);
                }
                // 为了后面展示未执行的任务，这里重写toString()方法
                @Override
                public String toString() {
                    return "这是第" + str + "个任务";
                }
            });
        }
//        service.shutdown();

        // 没有来得及执行的任务会以列表的形式返回
        List<Runnable> runnables = service.shutdownNow();
        if (service.isShutdown()) {
            System.out.println("----isShutdown-");
        }
        System.out.println("线程池已关闭");
        for (Runnable runnable : runnables) {
            // 打印一下未执行的任务
            System.out.println(runnable);
        }
    }

    /**
     * 自定义线程：测试等待队列长度很短的情况
     * 队列最长为3，看看添加到第4个，逻辑会怎么走
     * 结论：队列太短，那么进不了队列的任务可能会像核心任务一样直接运行
     */
    public void m9() {
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 8,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(2));

        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": start");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
        }

        executorService.shutdown();

        System.out.println("-----over");
    }

    /**
     * 自定义线程：测试等待队列长度很长的情况
     *
     */
    public void m10() {
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 4,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(10));

        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": start");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
        }

        executorService.shutdownNow();

        System.out.println("-----over");
    }

    public void m11() {
        //查数据类型有几位
        System.out.println(Byte.SIZE);//8
        System.out.println(Short.SIZE);//16
        System.out.println(Integer.SIZE);//32
        System.out.println(Long.SIZE);//64
        System.out.println(Float.SIZE);//32
        System.out.println(Double.SIZE);//64

        System.out.println(Integer.BYTES);//4

    }

}
